home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / hack / 2_3 / termcap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-20  |  8.4 KB  |  399 lines

  1. /*    SCCS Id: @(#)termcap.c    2.3    87/12/12
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3.  
  4. #include <stdio.h>
  5. #include <ctype.h>    /* for isdigit() */
  6. #include "hack.h"    /* for ROWNO, COLNO, *HI, *HE */
  7. #ifdef GENIX
  8. #define    void    int    /* jhn - mod to prevent compiler from bombing */
  9. #endif
  10.  
  11. extern char *tgetstr(), *tgoto(), *getenv();
  12. extern long *alloc();
  13.  
  14. #ifndef SYSV
  15. # ifndef LINT
  16. extern            /* it is defined in libtermlib (libtermcap) */
  17. # endif
  18.     short ospeed;    /* terminal baudrate; used by tputs */
  19. #else
  20. short    ospeed = 0;    /* gets around "not defined" error message */
  21. #endif
  22.  
  23. static char tbuf[512];
  24. static char *HO, *CL, *CE, *UP, *CM, *ND, *XD, *BC, *SO, *SE, *TI, *TE;
  25. static char *VS, *VE, *US, *UE;
  26. static int SG;
  27. static char PC = '\0';
  28. char *CD;        /* tested in pri.c: docorner() */
  29. int CO, LI;        /* used in pri.c and whatis.c */
  30.  
  31. #if defined(MSDOS) && !defined(TERMLIB)
  32. static char tgotobuf[20];
  33. #define tgoto(fmt, x, y)    (sprintf(tgotobuf, fmt, y+1, x+1), tgotobuf)
  34. #endif /* MSDOS /**/
  35.  
  36. startup()
  37. {
  38.     register char *term;
  39.     register char *tptr;
  40.     char *tbufptr, *pc;
  41.     register int i;
  42.  
  43.     tptr = (char *) alloc(1024);
  44.  
  45.     tbufptr = tbuf;
  46.     if(!(term = getenv("TERM")))
  47.         error("Can't get TERM.");
  48.     if(!strncmp(term, "5620", 4))
  49.         flags.nonull = 1;    /* this should be a termcap flag */
  50.     if(tgetent(tptr, term) < 1)
  51.         error("Unknown terminal type: %s.", term);
  52.     if(pc = tgetstr("pc", &tbufptr))
  53.         PC = *pc;
  54.     if(!(BC = tgetstr("bc", &tbufptr))) {    
  55.         if(!tgetflag("bs"))
  56.             error("Terminal must backspace.");
  57.         BC = tbufptr;
  58.         tbufptr += 2;
  59.         *BC = '\b';
  60.     }
  61.     HO = tgetstr("ho", &tbufptr);
  62.     CO = tgetnum("co");
  63.     LI = tgetnum("li");
  64.     if(CO < COLNO || LI < ROWNO+2)
  65.         setclipped();
  66.     if(!(CL = tgetstr("cl", &tbufptr)))
  67.         error("Hack needs CL.");
  68.     ND = tgetstr("nd", &tbufptr);
  69.     if(tgetflag("os"))
  70.         error("Hack can't have OS.");
  71.     CE = tgetstr("ce", &tbufptr);
  72.     UP = tgetstr("up", &tbufptr);
  73.     /* It seems that xd is no longer supported, and we should use
  74.        a linefeed instead; unfortunately this requires resetting
  75.        CRMOD, and many output routines will have to be modified
  76.        slightly. Let's leave that till the next release. */
  77.     XD = tgetstr("xd", &tbufptr);
  78. /* not:         XD = tgetstr("do", &tbufptr); */
  79.     if(!(CM = tgetstr("cm", &tbufptr))) {
  80.         if(!UP && !HO)
  81.             error("Hack needs CM or UP or HO.");
  82.         printf("Playing hack on terminals without cm is suspect...\n");
  83.         getret();
  84.     }
  85.     SO = tgetstr("so", &tbufptr);
  86.     SE = tgetstr("se", &tbufptr);
  87.     US = tgetstr("us", &tbufptr);
  88.     UE = tgetstr("ue", &tbufptr);
  89.     SG = tgetnum("sg");    /* -1: not fnd; else # of spaces left by so */
  90.     if(!SO || !SE || (SG > 0)) SO = SE = US = UE = "";
  91.     TI = tgetstr("ti", &tbufptr);
  92.     TE = tgetstr("te", &tbufptr);
  93.     VS = VE = "";
  94. #if defined(SORTING) || defined(MSDOSCOLOR)
  95.     /* Get rid of padding numbers for HI and HE.  Hope they
  96.      * aren't really needed!!!  HI and HE are ouputted to the
  97.      * pager as a string - so how can you send it NULLS???
  98.      *  -jsb
  99.      */
  100.         HI = (char *) alloc((unsigned)(strlen(SO)+1));
  101.         HE = (char *) alloc((unsigned)(strlen(SE)+1));
  102.         i = 0;
  103.         while(isdigit(SO[i])) i++;
  104.         strcpy(HI, &SO[i]);
  105.         i = 0;
  106.         while(isdigit(SE[i])) i++;
  107.         strcpy(HE, &SE[i]);
  108. #endif
  109.     CD = tgetstr("cd", &tbufptr);
  110.     set_whole_screen();        /* uses LI and CD */
  111.     if(tbufptr-tbuf > sizeof(tbuf)) error("TERMCAP entry too big...\n");
  112.     free(tptr);
  113. #ifdef MSDOSCOLOR
  114.     init_hilite();
  115. #endif
  116. }
  117.  
  118. start_screen()
  119. {
  120.     xputs(TI);
  121.     xputs(VS);
  122. #ifdef DGK
  123.     /* Select normal ASCII and line drawing character sets.
  124.      */
  125.     if (flags.DECRainbow)
  126.         xputs("\033(B\033)0");
  127. #endif
  128. }
  129.  
  130. end_screen()
  131. {
  132.     clear_screen();
  133.     xputs(VE);
  134.     xputs(TE);
  135. }
  136.  
  137. /* Cursor movements */
  138. extern xchar curx, cury;
  139.  
  140. curs(x, y)
  141. register int x, y;    /* not xchar: perhaps xchar is unsigned and
  142.                curx-x would be unsigned as well */
  143. {
  144.  
  145.     if (y == cury && x == curx)
  146.         return;
  147.     if(!ND && (curx != x || x <= 3)) {    /* Extremely primitive */
  148.         cmov(x, y);            /* bunker!wtm */
  149.         return;
  150.     }
  151.     if(abs(cury-y) <= 3 && abs(curx-x) <= 3)
  152.         nocmov(x, y);
  153.     else if((x <= 3 && abs(cury-y)<= 3) || (!CM && x<abs(curx-x))) {
  154.         (void) putchar('\r');
  155.         curx = 1;
  156.         nocmov(x, y);
  157.     } else if(!CM) {
  158.         nocmov(x, y);
  159.     } else
  160.         cmov(x, y);
  161. }
  162.  
  163. nocmov(x, y)
  164. {
  165.     if (cury > y) {
  166.         if(UP) {
  167.             while (cury > y) {    /* Go up. */
  168.                 xputs(UP);
  169.                 cury--;
  170.             }
  171.         } else if(CM) {
  172.             cmov(x, y);
  173.         } else if(HO) {
  174.             home();
  175.             curs(x, y);
  176.         } /* else impossible("..."); */
  177.     } else if (cury < y) {
  178.         if(XD) {
  179.             while(cury < y) {
  180.                 xputs(XD);
  181.                 cury++;
  182.             }
  183.         } else if(CM) {
  184.             cmov(x, y);
  185.         } else {
  186.             while(cury < y) {
  187.                 xputc('\n');
  188.                 curx = 1;
  189.                 cury++;
  190.             }
  191.         }
  192.     }
  193.     if (curx < x) {        /* Go to the right. */
  194.         if(!ND) cmov(x, y); else    /* bah */
  195.             /* should instead print what is there already */
  196.         while (curx < x) {
  197.             xputs(ND);
  198.             curx++;
  199.         }
  200.     } else if (curx > x) {
  201.         while (curx > x) {    /* Go to the left. */
  202.             xputs(BC);
  203.             curx--;
  204.         }
  205.     }
  206. }
  207.  
  208. cmov(x, y)
  209. register x, y;
  210. {
  211.     xputs(tgoto(CM, x-1, y-1));
  212.     cury = y;
  213.     curx = x;
  214. }
  215.  
  216. xputc(c) char c; {
  217.     (void) fputc(c, stdout);
  218. }
  219.  
  220. xputs(s) char *s; {
  221. #if defined(MSDOS) && !defined(TERMLIB)
  222.     fputs(s, stdout);
  223. #else
  224.     tputs(s, 1, xputc);
  225. #endif
  226. }
  227.  
  228. cl_end() {
  229.     if(CE)
  230.         xputs(CE);
  231.     else {    /* no-CE fix - free after Harold Rynes */
  232.         /* this looks terrible, especially on a slow terminal
  233.            but is better than nothing */
  234.         register cx = curx, cy = cury;
  235.  
  236.         while(curx < COLNO) {
  237.             xputc(' ');
  238.             curx++;
  239.         }
  240.         curs(cx, cy);
  241.     }
  242. }
  243.  
  244. clear_screen() {
  245.     xputs(CL);
  246.     home();
  247. }
  248.  
  249. home()
  250. {
  251.     if(HO)
  252.         xputs(HO);
  253.     else if(CM)
  254.         xputs(tgoto(CM, 0, 0));
  255.     else
  256.         curs(1, 1);    /* using UP ... */
  257.     curx = cury = 1;
  258. }
  259.  
  260. standoutbeg()
  261. {
  262.     if(SO) xputs(SO);
  263. }
  264.  
  265. standoutend()
  266. {
  267.     if(SE) xputs(SE);
  268. }
  269.  
  270. backsp()
  271. {
  272.     xputs(BC);
  273.     curx--;
  274. }
  275.  
  276. bell()
  277. {
  278. #ifdef DGKMOD
  279.     if (flags.silent) return;
  280. #endif /* DGKMOD /**/
  281.     (void) putchar('\007');        /* curx does not change */
  282.     (void) fflush(stdout);
  283. }
  284.  
  285. static short tmspc10[] = {        /* from termcap */
  286.     0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5
  287. };
  288.  
  289. delay_output() {
  290.     /* delay 50 ms - could also use a 'nap'-system call */
  291.     /* BUG: if the padding character is visible, as it is on the 5620
  292.        then this looks terrible. */
  293. #ifdef MSDOS
  294.     /* simulate the delay with "cursor here" */
  295.     register i;
  296.     for (i = 0; i < 3; i++) {
  297.         cmov(curx, cury);
  298.         (void) fflush(stdout);
  299.     }
  300. #else /* MSDOS /**/
  301.     if(!flags.nonull)
  302. #ifdef TERMINFO
  303.         tputs("$<50>", 1, xputs);
  304. #else
  305.         tputs("50", 1, xputs);
  306. #endif
  307.         /* cbosgd!cbcephus!pds for SYS V R2 */
  308.         /* is this terminfo, or what? */
  309.         /* tputs("$<50>", 1, xputc); */
  310.  
  311.     else if(ospeed > 0 || ospeed < SIZE(tmspc10)) if(CM) {
  312.         /* delay by sending cm(here) an appropriate number of times */
  313.         register int cmlen = strlen(tgoto(CM, curx-1, cury-1));
  314.         register int i = 500 + tmspc10[ospeed]/2;
  315.  
  316.         while(i > 0) {
  317.             cmov(curx, cury);
  318.             i -= cmlen*tmspc10[ospeed];
  319.         }
  320.     }
  321. #endif /* MSDOS /**/
  322. }
  323.  
  324. cl_eos()            /* free after Robert Viduya */
  325. {                /* must only be called with curx = 1 */
  326.  
  327.     if(CD)
  328.         xputs(CD);
  329.     else {
  330.         register int cx = curx, cy = cury;
  331.         while(cury <= LI-2) {
  332.             cl_end();
  333.             xputc('\n');
  334.             curx = 1;
  335.             cury++;
  336.         }
  337.         cl_end();
  338.         curs(cx, cy);
  339.     }
  340. }
  341.  
  342. #ifdef MSDOSCOLOR
  343. /* Sets up highlighting, using ANSI escape sequences, for monsters and 
  344.  * objects (highlight code found in pri.c). 
  345.  * The termcap entry for HI (from SO) is scanned to find the background 
  346.  * color. If everything is o.k., monsters are displayed in the color 
  347.  * used to define HILITE_MONSTER and objects are displayed in the color 
  348.  * used to define HILITE_OBJECT. */
  349.  
  350. #define ESC        0x1b
  351. #define NONE        0
  352. #define HIGH_INTENSITY    1
  353. #define BLACK        0
  354. #define RED        1
  355. #define GREEN        2
  356. #define YELLOW        3
  357. #define BLUE        4
  358. #define MAGENTA        5
  359. #define CYAN        6
  360. #define WHITE        7
  361.  
  362. #define HILITE_ATTRIB    NONE
  363. #define HILITE_MONSTER    RED
  364. #define HILITE_OBJECT    YELLOW
  365.  
  366. init_hilite()
  367. {
  368.     register int backg, len, mfore, ofore;
  369.  
  370.     backg = BLACK;
  371.     mfore = ofore = WHITE;
  372.     /* find the background color, HI[len] == 'm' */
  373.     len = strlen(HI) - 1;
  374.     if (len > 3) 
  375.     if (isdigit(HI[len-1]) && 
  376.         isdigit(HI[len-2]) && HI[len-2] != 3) {
  377.             backg = HI[len-1] - '0';
  378.             mfore = HILITE_MONSTER;
  379.             ofore = HILITE_OBJECT;
  380.     }
  381.     if (mfore == backg || ofore == backg) {
  382.         if (len < 7) mfore = ofore = WHITE;
  383.         else {
  384.             if (HI[2] == '3') mfore = ofore = HI[3] - '0';
  385.             else if (HI[4] == '3') mfore = ofore = HI[5] - '0';
  386.             else mfore = ofore = WHITE; /* give up! */
  387.         }
  388.     }
  389.  
  390.     HI_MON = (char *) alloc(sizeof("E[0;33;44;54m"));
  391.     sprintf(HI_MON, "%c[%d;3%d;4%dm", ESC, HILITE_ATTRIB, 
  392.             mfore, backg);
  393.     HI_OBJ = (char *) alloc(sizeof("E[0;33;44;54m"));
  394.     sprintf(HI_OBJ, "%c[%d;3%d;4%dm", ESC, HILITE_ATTRIB, 
  395.             ofore, backg);
  396. }
  397.  
  398. #endif
  399.